# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name：     non_terminator
   Description :
   Author :       Flyoung
   date：          2023/4/16
-------------------------------------------------
   Change Activity:
                   2023/4/16:
-------------------------------------------------
"""
from data_structure.string import String
from lib import epsilon


class NonTerminator:
    def __init__(self, name: String):
        # 非终结符
        self.name = name
        self.equal_list: list[String] = list()
        self.First: set[String] = set()
        self.Follow: set[String] = set()

    def __hash__(self):
        return hash(self.name.content)

    def __eq__(self, other):
        if isinstance(other, NonTerminator):
            return self.name == other.name
        return False

    def __str__(self) -> str:
        return f'{self.name.content} -> {" | ".join([i.__str__() for i in self.equal_list])}'

    def is_derive_epsilon(self) -> bool:
        """
        能否推导出 epsilon
        :return:
        """
        if epsilon in self.equal_list:
            return True
        return False

    def get_follow_set_size(self) -> int:
        """
        获取 follow 集合元素个数
        :return:
        """
        return len(self.Follow)

    def update_follow_set(self, follow_set: set[String]) -> bool:
        """
        更新 Follow 集合
        :param follow_set:
        :return: 集合元素是否有变化
        """
        if String(epsilon) in follow_set:
            follow_set.remove(String(epsilon))
        before_update_size = self.get_follow_set_size()
        self.Follow.update(follow_set)
        return before_update_size != self.get_follow_set_size()

    def get_follow_set_str(self) -> str:
        """
        获取 follow 集合表示
        :return:
        """
        return f'Follow({self.name}) = {{ {", ".join([i.__str__() for i in self.Follow])} }}'

    def get_first_set_str(self) -> str:
        """
        获取 first 集合表示
        :return:
        """
        return f'First({self.name}) = {{ {", ".join([i.__str__() for i in self.First])} }}'
